<div class="tutorial-bundle" data-metadata-json='{"programKind": "per-method", "difficulty": "medium", "groupedProjectAssets": [{"name": "Cartoon fruit", "assets": ["Apple-1.png", "Apple-2.png", "Apple-3.png", "Apple-4.png", "GoldApple-1.png", "Lemon-1.png", "Lemon-2.png", "Lemon-3.png", "Lemon-4.png", "Orange-1.png", "Orange-2.png", "Orange-3.png", "Orange-4.png", "Strawberry-1.png"]}, {"name": "Pytch snake", "assets": ["Pytch-snake-1.png", "Pytch-snake-2.png", "Pytch-snake-3.png", "Pytch-snake-4.png"]}, {"name": "Fruit bowl", "assets": ["Bowl-1.png", "Bowl-2.png"]}]}' data-tip-sha1="904bf85f4bb0677362f0598c5f936d371547d61f"><div class="front-matter" data-complete-code-text='import pytch
import random


class Bowl(pytch.Sprite):
    Costumes = ["Bowl-1.png", "Bowl-2.png"]

    @pytch.when_green_flag_clicked
    def move_with_keys(self):
        self.set_size(0.3)
        self.go_to_xy(0, -145)

        while True:
            if pytch.key_pressed("a"):
                if self.x_position &gt; -145:
                    self.change_x(-2)
            if pytch.key_pressed("d"):
                if self.x_position &lt; 190:
                    self.change_x(2)


class Apple(pytch.Sprite):
    Costumes = [
        "Apple-1.png",
        "Apple-2.png",
        "Apple-3.png",
        "Apple-4.png",
        "GoldApple-1.png",
        "Lemon-1.png",
        "Lemon-2.png",
        "Lemon-3.png",
        "Lemon-4.png",
        "Orange-1.png",
        "Orange-2.png",
        "Orange-3.png",
        "Orange-4.png",
        "Strawberry-1.png"
    ]

    @pytch.when_I_receive("drop-apple")
    def move_down_stage(self):
        self.set_size(0.25)
        drop_x = random.randint(-145, 190)
        self.go_to_xy(drop_x, 200)
        self.show()
        while self.y_position &gt; -140:
            self.change_y(-3)
            if self.touching(Bowl):
                self.hide()
                pytch.broadcast("award-point")


class ScoreKeeper(pytch.Sprite):
    Costumes = [
        "Pytch-snake-1.png",
        "Pytch-snake-2.png",
        "Pytch-snake-3.png",
        "Pytch-snake-4.png"
    ]

    @pytch.when_green_flag_clicked
    def initialise(self):
        self.set_size(0.6)
        self.go_to_xy(-260, -105)
        self.score = 0
        self.say(self.score)

    @pytch.when_I_receive("award-point")
    def award_point(self):
        self.score += 1
        self.say(self.score)

    @pytch.when_green_flag_clicked
    def drop_apples(self):
        while True:
            pytch.broadcast_and_wait("drop-apple")
' data-initial-code-text="import pytch
import random
"><h1>Catch the apple!</h1><p>This tutorial will show you how to make a simple game in Pytch.  The
player will move a bowl to try to catch apples which fall down the
stage.</p><p><img alt="Screenshot" src="screenshot-w240.png#img-center"/></p><p>You’ll develop the game in stages.  If you know Scratch, that will
help with understanding how things work in Python, but isn’t
essential.</p></div><div class="chapter-content"><h2>Add a <em>Sprite</em> for the player's bowl</h2><p>We’ll start with the bowl which the player controls.  Just like in
Scratch, we add a <em>Sprite</em>.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a Sprite called <code>Bowl</code> to your project.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-sprite", "name": "Bowl"}' data-slug="add-empty-Bowl"></div>
</div></div><p>If you run this now, you won’t see anything.  This is because we
haven’t given our Sprite any <em>costumes</em>.</p><h3>Add a costume for the Sprite</h3><p>Pytch sprites have <em>costumes</em> just like Scratch sprites do.</p><p>The costume we want to use is part of the <em>Fruit bowl</em> bundle of
images in the Pytch media library.</p><div class="learner-task"><div class="learner-task-intro">
<p>Using the media library, add the “Fruit bowl” bundle of images as
costumes for your <code>Bowl</code> sprite.  The first costume, which the sprite
will use by default, is of an empty bowl.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-medialib-appearances-entry", "actor": {"kind": "sprite", "name": "Bowl"}, "displayIdentifier": "Fruit bowl", "nItems": 2}' data-slug="add-Bowl-costumes"></div>
</div></div><p>Now, if you click the green flag, you should see the player’s bowl
appear in the middle of the stage.  Test that now!</p><h3>Test it!</h3><div class="learner-task"><div class="learner-task-intro">
<p>Try your game.  What’s wrong?</p>
</div><div class="learner-task-help">
<p>The bowl is huge!</p>
</div></div><h3>Set the Bowl’s size</h3><p>When the game first starts, the Bowl needs to run some code which sets
its size to something more sensible.  We do this, like in Scratch, by
adding a script to our Sprite.  The difference is that in Pytch, we’ll
type Python code into the script, instead of clicking blocks together
like we would do in Scratch.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a new script to the <code>Bowl</code> sprite which will run when the player
clicks the green flag.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-script", "path": {"actor": {"kind": "sprite", "name": "Bowl"}, "methodName": "move_with_keys"}, "event": {"kind": "green-flag"}, "codeText": ""}' data-slug="add-empty-move-with-keys-handler"></div>
</div></div><p>You write Python code in this script which sets the Bowl’s size.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add code to this script which sets the Bowl’s size.  The help
information in the sidebar might be useful.  Think about what size
would work for the game.</p>
</div><div class="learner-task-help">
<p>A size of <code>0.3</code> seems about right, but you can adjust this number if
you think the Bowl should be a bit bigger or smaller.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Bowl"}, "methodName": "move_with_keys"}, "event": {"kind": "green-flag"}, "oldCodeText": "", "newCodeText": "self.set_size(0.3)"}' data-slug="set-Bowl-size"></div>
</div></div></div><div class="chapter-content"><h2>Start the bowl in the right place</h2><p>The player needs to be able to move the bowl.  We’ll let them do this
with the keyboard, using the <code>a</code> and <code>d</code> keys.</p><p>We’ll start off by adding code which moves the bowl to a sensible
place at the bottom of the stage when the game starts.</p><p>Pytch uses the same way of describing positions on the
stage as Scratch.  You can use the <em>Show coordinates</em> tool to find
suitable coordinate values.  A <code>x</code>-coordinate of <code>0</code> puts the bowl in
the centre, left-to-right.  I picked <code>-150</code> for the <code>y</code>-coordinate, to
put the bowl almost at the bottom.</p><p>In Scratch, we would use a block like this:</p><pre><code class="language-scratch">go to x: [0] y: [-150]
</code></pre><p>In Python, you write code to do the same job.  You provide the extra
pieces of information (called “arguments”) in brackets “<code>()</code>” after
the method name.  This is the code we need:</p><pre><code class="language-python">self.go_to_xy(0, -150)
</code></pre><p>The “<code>self.</code>” part at the start means we want the Sprite itself to do
something.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add this code to the script you have just made.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Bowl"}, "methodName": "move_with_keys"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.3)", "newCodeText": "self.set_size(0.3)\nself.go_to_xy(0, -145)"}' data-slug="move-Bowl-to-starting-point"></div>
</div></div><p>Now, when you click the green flag, the bowl should move to its
starting position at the bottom of the stage.  Try it!</p></div><div class="chapter-content"><h2>Let the player move the bowl</h2><p>Now we’re going to let the player move the bowl.  We’ll start by
letting them move it to the right.  We’ll keep checking whether the
player is pressing the <code>d</code> key, and if so, change the bowl’s
<code>x</code>-coordinate.  In Scratch we could do this with a <em>forever</em> block:</p><pre><code class="language-scratch">forever:
  if &lt;key [d v] pressed&gt; then:
    change x by (2)
</code></pre><p>Python has the <code>while True:</code> statement to do the same job.  In
Scratch, we put the blocks we want to run forever <em>inside</em> the
<em>forever</em> block.  In Python, we <em>indent</em> the code we want to run
forever to the right <em>under</em> the <code>while True:</code>.</p><p>Python’s <em>if</em> statement works in the same way.  The code you want to
run only if the condition is true is indented to the right.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add code which keeps checking whether the player is pressing the <code>d</code>
key, and, if so, changes the bowl’s <code>x</code>-coordinate by 2.</p>
</div><div class="learner-task-help">
<p>Use the Scratch/Python help (click the circled <code>?</code> icon at top-left)
to learn how you can write '<em>key <code>d</code> pressed</em>' and '<em>change x by 2</em>'
in Python.  Then come back to this tutorial by clicking on the book
icon.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Bowl"}, "methodName": "move_with_keys"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.3)\nself.go_to_xy(0, -145)", "newCodeText": "self.set_size(0.3)\nself.go_to_xy(0, -145)\n\nwhile True:\n    if pytch.key_pressed(\"d\"):\n        self.change_x(2)"}' data-slug="move-bowl-right"></div>
</div></div><p>If you try this, it should let you move the bowl right by holding down
the <code>d</code> key.  But!  You can move the bowl all the way off the stage.
We’ll fix that next.</p><h3>Keep the bowl on the stage</h3><p>If the player is pressing <code>d</code>, we then need to check whether it’s OK
to move the bowl rightwards.  We do this be checking the bowl’s
<code>x</code>-coordinate.  When the bowl is as far to the right as possible, the
<code>x</code>-coordinate is <code>190</code> — I found this value by trial and error in the
code below.  It’s OK to move right as long as the <code>x</code>-coordinate is
less than or equal to 190.  We can add another <code>if</code> statement to test
for this, and only do the <code>self.change_x(2)</code> if the test passes.</p><div class="learner-task"><div class="learner-task-intro">
<p>Change your script so that it also checks whether the bowl’s
<code>x</code>-coordinate is less than 190, and only moves rightwards if it is.</p>
</div><div class="learner-task-help">
<p>In scratch, we would move the block</p>
<pre><code class="language-scratch">change x by (2)
</code></pre>
<p>to be inside an 'if' block, like this:</p>
<pre><code class="language-scratch">if &lt;(x position) &lt; [190]&gt; then:
  change x by (2)
</code></pre>
<p>In Python, we use another <code>if</code> statement and <em>indent</em> the code which
changes <code>x</code>.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Bowl"}, "methodName": "move_with_keys"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.3)\nself.go_to_xy(0, -145)\n\nwhile True:\n    if pytch.key_pressed(\"d\"):\n        self.change_x(2)", "newCodeText": "self.set_size(0.3)\nself.go_to_xy(0, -145)\n\nwhile True:\n    if pytch.key_pressed(\"d\"):\n        if self.x_position &lt; 190:\n            self.change_x(2)"}' data-slug="clamp-bowl-at-right"></div>
</div></div><p>Test this now — click the green flag, then check you can still move
rightwards, but only as far as the edge of the stage.</p><h3>Let the player move left too</h3><p>The same idea will let the player move <em>left</em> as well.  A natural
place for this new code is in the same <code>while True:</code> loop which
already lets the player move right.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add code to let the player move left.</p>
<p>Add code to the <code>while</code> loop inside the green-flag script, so the
player can move left using the <code>"a"</code> key.  Make sure that they can’t
move the bowl too far to the left.  They should still be able to move
right.</p>
</div><div class="learner-task-help">
<p>Look at the existing code for moving <em>right</em>, which will be a useful
guide, because the task is very similar.  Think carefully about what
needs to change, about each part of the code, for moving <em>left</em>.</p>
</div><div class="learner-task-help">
<p>The differences for moving left instead of right are:</p>
<ul>
<li>Check for the <code>"a"</code> key not the <code>"d"</code> key.</li>
<li>Check that the bowl is not too far <em>left</em> already, by checking that
  its <code>x</code>-coordinate is more than <code>-145</code>.  (This leaves a bit of room
  at the very left for a score-keeper to stand — we'll come to the
  score-keeper later in the tutorial.)</li>
<li>Move by using a <em>negative</em> value for the amount the bowl should
  change its <code>x</code>-coordinate by.</li>
</ul>
<p>You can copy and paste the existing lines of code, and modify the copy
to make this list of changes.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Bowl"}, "methodName": "move_with_keys"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.3)\nself.go_to_xy(0, -145)\n\nwhile True:\n    if pytch.key_pressed(\"d\"):\n        if self.x_position &lt; 190:\n            self.change_x(2)", "newCodeText": "self.set_size(0.3)\nself.go_to_xy(0, -145)\n\nwhile True:\n    if pytch.key_pressed(\"a\"):\n        if self.x_position &gt; -145:\n            self.change_x(-2)\n    if pytch.key_pressed(\"d\"):\n        if self.x_position &lt; 190:\n            self.change_x(2)"}' data-slug="move-clamp-bowl-left"></div>
</div></div></div><div class="chapter-content"><h2>Add a Sprite for the apple</h2><p>We now need something for the player to catch.  We’ll create another
Sprite for this.</p><div class="learner-task"><div class="learner-task-intro">
<p>Make a new sprite called “Apple”.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-sprite", "name": "Apple"}' data-slug="add-empty-Apple-class"></div>
</div></div><p>Next is to give the apple a costume.  The media library has a bundle
of cartoon fruit which includes some apples.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add the <em>Cartoon fruit</em> bundle of images from the media library to this new
sprite.  The first costume in the bundle is an apple.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-medialib-appearances-entry", "actor": {"kind": "sprite", "name": "Apple"}, "displayIdentifier": "Cartoon fruit", "nItems": 14}' data-slug="give-Apple-costumes"></div>
</div></div><p>If you run the project now, an apple should appear in the middle of
the Stage.</p><div class="learner-task"><div class="learner-task-intro">
<p>Try your game.  What’s wrong?</p>
</div><div class="learner-task-help">
<p>The apple is huge!</p>
</div></div><h3>Make the apple a sensible size</h3><p>This is very similar to how we made the Bowl the right size.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a new script to the <code>Apple</code> sprite which will run when the player
clicks the green flag.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "codeText": ""}' data-slug="add-empty-Apple-script"></div>
</div></div><p>And write Python code in this script.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add code to this script which sets the Apple’s size.  You can use the
code you wrote for the Bowl as a guide.</p>
</div><div class="learner-task-help">
<p>A size of <code>0.25</code> seems about right, but you can adjust this number if you
like.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "oldCodeText": "", "newCodeText": "self.set_size(0.25)"}' data-slug="set-Apple-size"></div>
</div></div></div><div class="chapter-content"><h2>Make the apple fall down the stage</h2><p>To give the apple its behaviour, we’ll add a script.  In more detail:</p><ul>
<li>We want this code to run when the green flag is clicked.</li>
<li>Add a line of code to the script line which moves the apple to a
  good starting point on the stage — I chose just off the top of the
  stage, and off-centre to the right a bit, coordinates
  (100, 200).</li>
</ul><div class="learner-task"><div class="learner-task-intro">
<p>Add a line of code to the Apple’s script which does this.</p>
</div><div class="learner-task-help">
<p>You need to work out what Python code will do the same job as this
Scratch block:</p>
<pre><code class="language-scratch">go to x: [100] y: [200]
</code></pre>
<p>Use the Scratch/Python help, or look back at how you got the bowl to
start at the right place.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.25)", "newCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)"}' data-slug="move-Apple-to-starting-point"></div>
</div></div><p>If you try this now (click the green flag), you should just be able to
see the bottom of the apple at the top of the stage.</p><h3>Actually move down the stage</h3><p>What we want the apple to do is keep moving down, as long as it is
above the bottom of the stage.  In Scratch we could use a <code>repeat
until</code> block.  Python has a <code>while</code> statement instead.  This is very
like Scratch’s <code>repeat until</code> block, but uses the test ‘the other way
round’ —</p><ul>
<li>Scratch’s <code>repeat until</code> block keeps running the contained blocks,
  and <em>stops when the test is true</em>.</li>
<li>Python’s <code>while</code> statement checks the test, and <em>runs the contained
  code while the test is true</em>.</li>
</ul><p>We want to test whether the apple’s <code>y</code>-coordinate is higher than some
value near the bottom of the stage.  By trial and error, I found that
<code>-140</code> worked well for this.  We want to add code which, in words, does</p><blockquote>
<p>while the <code>y</code>-coordinate is bigger than <code>-140</code>, move down by 3</p>
</blockquote><div class="learner-task"><div class="learner-task-intro">
<p>Add code to your script which does this.</p>
</div><div class="learner-task-help">
<p>You need to add two lines of code to the end of your script.</p>
</div><div class="learner-task-help">
<p>For ‘move down’, you can use <code>self.change_y()</code> with a negative value
for the argument.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)", "newCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)"}' data-slug="make-apple-fall-down-screen"></div>
</div></div><p>If you run this code, the apple should fall down the stage, and stop
at the bottom.</p><p>The <code>while</code> here might look different to when we used <code>while True:</code> to
mean “forever”, but it’s really just different ways of using the same
part of the Python language.  When we want something to happen
forever, the <code>True</code> in <code>while True:</code> acts as a test which always
passes, so the indented code keeps running again and again forever.</p></div><div class="chapter-content"><h2>Catch the apple in the bowl</h2><p>Finally, we want to let the player catch the apple.  Each time the
apple moves, it can check whether it’s been caught.  This happens if
the apple is touching the bowl.  If it is, then we want to hide the
apple.  What we want to do is the Python equivalent of the Scratch
script</p><pre><code class="language-scratch">if &lt; touching (Bowl v)?&gt; then
hide
</code></pre><div class="learner-task"><div class="learner-task-intro">
<p>Add code to your script which hides the apple if it touches the bowl.</p>
</div><div class="learner-task-help">
<p>You can use the Scratch/Python help to find out what Pytch functions
work the same as the Scratch</p>
<pre><code class="language-scratch">touching (Bowl v)
</code></pre>
<p>and</p>
<pre><code class="language-scratch">hide
</code></pre>
<p>blocks.</p>
</div><div class="learner-task-help">
<p>You will need an <code>if</code> statement at the end of the script, still
"inside" the <code>while</code> loop body.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)", "newCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()"}' data-slug="hide-Apple-when-caught"></div>
</div></div></div><div class="chapter-content"><h2>Add the score-keeper</h2><p>The next piece we want to work on is a score-keeper, who will keep
track of how many apples the player has caught in their bowl.</p><p>By now, we know how the start of this job works:</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a Sprite called <code>ScoreKeeper</code>.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-sprite", "name": "ScoreKeeper"}' data-slug="define-skeleton-ScoreKeeper-sprite"></div>
</div></div><div class="learner-task"><div class="learner-task-intro">
<p>Give the score-keeper sprite a costume.  The first costume in the
<em>Pytch snake</em> bundle in the media library works well, or you can
choose a different one.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-medialib-appearances-entry", "actor": {"kind": "sprite", "name": "ScoreKeeper"}, "displayIdentifier": "Pytch snake", "nItems": 4}' data-slug="give-ScoreKeeper-costumes"></div>
</div></div><h3>Set the ScoreKeeper’s size</h3><p>By now you might expect that we need to set the ScoreKeeper’s size!</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a new script to the <code>ScoreKeeper</code> sprite which will run when the player
clicks the green flag.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "initialise"}, "event": {"kind": "green-flag"}, "codeText": ""}' data-slug="add-empty-ScoreKeeper-script"></div>
</div></div><div class="learner-task"><div class="learner-task-intro">
<p>Add code to this script which sets the ScoreKeeper’s size.</p>
</div><div class="learner-task-help">
<p>A size of <code>0.6</code> seems about right, but you can adjust this number if you
like.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "initialise"}, "event": {"kind": "green-flag"}, "oldCodeText": "", "newCodeText": "self.set_size(0.6)"}' data-slug="set-ScoreKeeper-size"></div>
</div></div><h3>Start the score-keeper in a sensible place</h3><p>We want to move the score-keeper to a sensible place when the green
flag is clicked.  Using the <em>Show coordinates</em> tool, the coordinates
(-260, -105) seem about right, but you can adjust the values if
you prefer.  This actually makes the snake’s tail disappear off to the
left, but it looks OK and leaves more room for the game.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add code to the script to move the score-keeper to a suitable place on
the stage.</p>
</div><div class="learner-task-help">
<p>You can refer to the other two Sprites if you'd like to remind
yourself what Python code to use to move a Sprite to a particular
place on the stage.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "initialise"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.6)", "newCodeText": "self.set_size(0.6)\nself.go_to_xy(-260, -105)"}' data-slug="move-ScoreKeeper-to-starting-point"></div>
</div></div></div><div class="chapter-content"><h2>Start off with zero points</h2><p>When the player starts the game, they should have no points.  We want
to define a new <em>variable</em> within the score-keeper.  This is just like
when you make a new <em>For this sprite only</em> variable in Scratch.  In
Python, there is no separate step to create the variable.  You just
set your variable to a value, and this automatically creates the
variable.</p><p>For example, to create a variable, within a sprite, referring to a
string, we could use code like</p><pre><code class="language-python">self.my_name = "Arthur"
</code></pre><p>The “<code>self.</code>” is what makes this variable like Scratch’s <em>For this
sprite only</em>.</p><p>We want set the starting value of a new <code>score</code> variable in the
score-keeper to the number zero.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add code to the score-keeper's script which makes a new variable
<code>score</code> with value <code>0</code>.</p>
</div><div class="learner-task-help">
<p>You can base your code on the example in the text above.  Your
variable should be called <code>score</code> (not <code>my_name</code>), and should be set
to the number <code>0</code> (not the string <code>"Arthur"</code>).</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "initialise"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.6)\nself.go_to_xy(-260, -105)", "newCodeText": "self.set_size(0.6)\nself.go_to_xy(-260, -105)\nself.score = 0"}' data-slug="add-ScoreKeeper-score-attribute"></div>
</div></div><p>The job of the score-keeper is to announce the score, so we want to
add a line to say the value of the <code>score</code> variable.  In Scratch we
would do this with a block</p><pre><code class="language-scratch">say (score)
</code></pre><p>You can use the Scratch/Python help content to find what Pytch
function does the same job as the “say” block.  Remember you’ll need
to say <code>self.score</code> to mean the score-keeper’s <code>score</code> variable.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a line of code which makes the score-keeper say the starting
score.</p>
</div><div class="learner-task-help">
<p>You'll need to add a line of code at the end of the script.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "initialise"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.6)\nself.go_to_xy(-260, -105)\nself.score = 0", "newCodeText": "self.set_size(0.6)\nself.go_to_xy(-260, -105)\nself.score = 0\nself.say(self.score)"}' data-slug="announce-starting-score"></div>
</div></div><p>If you run this now, the score-keeper should say “<code>0</code>”.</p></div><div class="chapter-content"><h2>Give a point for catching an apple</h2><p>The player can catch the apple in the bowl, but the score stays as
zero.  We will fix this next.</p><p>We’ll add another script to the score-keeper sprite.  The script’s
job will be to give the player a point, and announce the new score.</p><p>But first we need to think about when this code will run.  We want it
to run when the apple is caught by the bowl.  Like in Scratch, one
Sprite can <em>broadcast</em> a message which other sprites can react to.
We’ll use a message <code>"award-point"</code> which the score-keeper will react
to.  Later, we’ll make the apple broadcast this message when the
player’s bowl catches it.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a new empty script to the score-keeper which will run when it
receives the message <code>"award-point"</code>.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "award_point"}, "event": {"kind": "message-received", "message": "award-point"}, "codeText": ""}' data-slug="add-empty-award-point-handler"></div>
</div></div><p>Now we need to add code to this script which adds one to the
score-keeper’s <code>score</code> variable.  In Scratch you would say</p><pre><code class="language-scratch">change [score v] by (1)
</code></pre><p>Use the Scratch/Python help content to find the Python code which does
the same job.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a line of code to the new script which increases the
score-keeper’s <code>score</code> variable by one.</p>
</div><div class="learner-task-help">
<p>In the Scratch/Python help content, look in the “Working with
variables” section.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "award_point"}, "event": {"kind": "message-received", "message": "award-point"}, "oldCodeText": "", "newCodeText": "self.score += 1"}' data-slug="increment-score"></div>
</div></div><p>We also need to make sure the score-keeper says the new score.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add a line of code which makes the score-keeper say the new value of
its <code>score</code> variable.</p>
</div><div class="learner-task-help">
<p>The line will be the same as the line you added at the end of the last
chapter (to say the score after first setting it to zero).</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "award_point"}, "event": {"kind": "message-received", "message": "award-point"}, "oldCodeText": "self.score += 1", "newCodeText": "self.score += 1\nself.say(self.score)"}' data-slug="refresh-score-speech"></div>
</div></div><h3>Making the apple broadcast the message</h3><p>This code is correct, but so far nobody is broadcasting the
<code>award-point</code> message, and so our code never runs.</p><p>As we said earlier, the apple needs to broadcast this message when
it’s caught by the bowl.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add some code to the right script <strong>in your <code>Apple</code> sprite</strong> which
broadcasts the <code>award-point</code> message when it’s caught.</p>
</div><div class="learner-task-help">
<p>Make sure you choose the <code>Apple</code> sprite!</p>
</div><div class="learner-task-help">
<p>Think carefully about what section of your code runs when the apple is
caught — remember that our code checks for this by asking whether the
apple is touching the bowl.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()", "newCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")"}' data-slug="broadcast-when-apple-caught"></div>
</div></div><p>If you try this now, you should be able to get your score from zero to
one by catching the apple.</p></div><div class="chapter-content"><h2>Drop the apple from a random place</h2><p>So far the game drops the apple in the same place every time you play.
This makes the game far too easy.  We want to make the apple drop in a
random place each time.  We will use a <em>module</em> which comes with
Python — a <em>module</em> is some code, usually written by someone else,
which we can use in our program.</p><p>We will use a function in the <code>random</code> module which picks a random
whole number.  The function we want is called <code>randint</code> (for <em>random
integer</em>).  We need to say what the smallest and largest whole number
allowed are.  By trial and error, I worked out:</p><ul>
<li>The smallest (leftmost) <code>x</code>-coordinate which makes sure the apple
  doesn't hit the score-keeper is <code>-145</code>.</li>
<li>The largest (rightmost) <code>x</code>-coordinate which makes sure the apple
  isn’t off the right edge of the stage is <code>190</code>.</li>
</ul><p>So these are the arguments we want give to the <code>random.randint</code>
function, and we set a new variable <code>drop_x</code> to the result.  In
Scratch, this whole thing would look like</p><pre><code class="language-scratch">set [drop_x v] to (pick random [-145] to [190])
</code></pre><div class="learner-task"><div class="learner-task-intro">
<p>Add a line at the start of the apple's script which creates a variable
<code>drop_x</code>, equal to the result of calling <code>random.randint()</code> with the
argument values just described.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.25)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")", "newCodeText": "self.set_size(0.25)\ndrop_x = random.randint(-145, 190)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")"}' data-slug="choose-random-drop-x"></div>
</div></div><p>Now we need to use the value of our <code>drop_x</code> variable instead of the
fixed <code>100</code> for the <code>x</code>-coordinate of where the apple falls from.</p><div class="learner-task"><div class="learner-task-intro">
<p><em>Change</em> the code which calls the <code>go_to_xy()</code> function so that
instead of using <code>100</code> for the <code>x</code>-coordinate argument, it uses the
<code>drop_x</code> variable.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "green-flag"}, "oldCodeText": "self.set_size(0.25)\ndrop_x = random.randint(-145, 190)\nself.go_to_xy(100, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")", "newCodeText": "self.set_size(0.25)\ndrop_x = random.randint(-145, 190)\nself.go_to_xy(drop_x, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")"}' data-slug="drop-from-random-abscissa"></div>
</div></div><p>One thing you might notice is that we didn’t say <code>self.drop_x</code> here,
we just said <code>drop_x</code>.  By not saying <code>self</code>, Python makes the
<code>drop_x</code> variable only exist inside this script.  Since we won't need
<code>drop_x</code> anywhere else, this avoids cluttering up our project.</p><p>Now the game is better — each time we play the game, by clicking the
green flag, the apple falls from a different place.</p></div><div class="chapter-content"><h2>Make apples keep falling</h2><p>We’re going to change the game so that the score-keeper is in charge
of making the apple fall from the sky.  It will do this by
broadcasting a message every time the apple should fall.</p><p>For the apple script, this means that the script should <em>not</em> run when
the green flag is clicked.  Instead it should run when it receives a
message, let’s say <code>"drop-apple"</code>.</p><div class="learner-task"><div class="learner-task-intro">
<p>Change the hat-block of the apple's script so that the script runs
when the apple receives the message <code>"drop-apple"</code> (instead of when
the green flag is clicked).</p>
</div><div class="learner-task-help">
<p>Once you've found the right script, you can either double-click on the
hat-block, or choose <em>Change hat block</em> from the hat-block's drop-down
menu.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "change-hat-block", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "codeText": "self.set_size(0.25)\ndrop_x = random.randint(-145, 190)\nself.go_to_xy(drop_x, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")", "oldEvent": {"kind": "green-flag"}, "newEvent": {"kind": "message-received", "message": "drop-apple"}}' data-slug="launch-apple-on-message-not-green-flag"></div>
</div></div><p>Right now, the game won’t work, because nothing is broadcasting the
<code>"drop-apple"</code> message.  We’ll give that job to the score-keeper now.</p><p>We’ll make a new script in the score-keeper sprite which will keep
sending the message telling the apples to drop.  This script should
run when the green flag is clicked.</p><div class="learner-task"><div class="learner-task-intro">
<p>Add an empty script to the score-keeper which runs when the green flag
is clicked.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "add-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "drop_apples"}, "event": {"kind": "green-flag"}, "codeText": ""}' data-slug="add-empty-drop-apples-loop-script"></div>
</div></div><p>We want our new script to keep making apples drop from the top of the
stage forever.  Just like in the code which lets the player move the
bowl, we do this with Python’s <code>while True:</code> loop.  Inside that loop,
we want to keep broadcasting the message <code>"drop-apple"</code>.  Here, we
will use the <code>broadcast_and_wait()</code> function, because we don't want to
drop the next apple until the current one has either been caught or
reached the bottom of the stage.  In Scratch, the code would be</p><pre><code class="language-scratch">forever
broadcast (drop-apple v) and wait
</code></pre><div class="learner-task"><div class="learner-task-intro">
<p>Add the code to your new script which does the same job as these
Scratch blocks.</p>
</div><div class="learner-task-help">
<p>You will need <code>while True:</code> followed by an <em>indented</em> line of code.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "ScoreKeeper"}, "methodName": "drop_apples"}, "event": {"kind": "green-flag"}, "oldCodeText": "", "newCodeText": "while True:\n    pytch.broadcast_and_wait(\"drop-apple\")"}' data-slug="add-broadcast-drop-apple-loop"></div>
</div></div><p>If you try the game now, it doesn’t work!  What's happening is that
we’ve told the apple to <code>hide()</code> itself when it’s caught, but we
haven’t told it to <code>show()</code> itself when it starts dropping.</p><div class="learner-task"><div class="learner-task-intro">
<p>Fix this!  Work out where, <strong>in the <code>Apple</code>'s script</strong>, you need to
add a line of code which makes the apple show itself.</p>
</div><div class="learner-task-help">
<p>In the apple's script, there are two main sections.  The first section
chooses a random place to go to, and then goes to that place.  The
second section is the <code>while</code> loop which moves the apple down the
screen.  Just before the <code>while</code> loop (so at the end of the first,
"set-up" section) is a good place to put the <code>self.show()</code> we need.</p>
</div><div class="learner-task-help">
<div class="jr-commit" data-jr-commit='{"kind": "edit-script", "path": {"actor": {"kind": "sprite", "name": "Apple"}, "methodName": "move_down_stage"}, "event": {"kind": "message-received", "message": "drop-apple"}, "oldCodeText": "self.set_size(0.25)\ndrop_x = random.randint(-145, 190)\nself.go_to_xy(drop_x, 200)\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")", "newCodeText": "self.set_size(0.25)\ndrop_x = random.randint(-145, 190)\nself.go_to_xy(drop_x, 200)\nself.show()\nwhile self.y_position &gt; -140:\n    self.change_y(-3)\n    if self.touching(Bowl):\n        self.hide()\n        pytch.broadcast(\"award-point\")"}' data-slug="show-apple-when-fall-starts"></div>
</div></div><p>This is now a playable game written in Python — congratulations!</p><p>If you're using a shared computer, you can save your work using the
"Export to Google Drive" or "Download as zipfile" options from the
dropdown menu.</p></div><div class="chapter-content"><h2>Improve the game</h2><p>Here are some ideas on how you could make this game more fun:</p><ul>
<li>
<p>Add a <em>backdrop</em> to the stage, to make the game look more
  interesting.  You can use one from Pytch’s media library, or you can
  draw or find one of your own.</p>
</li>
<li>
<p>Add a pause between one apple being caught / missed and the next one
  appearing.  Use the Scratch/Python help to find the Pytch version of
  Scratch’s <code>wait () seconds</code> block.  (Hint: just before doing
  <code>pytch.broadcast_and_wait("drop-apple")</code> is a good place to pause.)</p>
</li>
<li>
<p>The <code>x</code>-coordinate where the apple starts is already random.  Make
  the starting <code>y</code>-coordinate be random too.  If an apple starts lower
  down the stage, the player has less time to get the bowl under the
  apple, making the game more challenging.</p>
</li>
<li>
<p>Change how quickly the player can move the bowl.  A bit quicker
  would make the game easier; a bit slower would make the game harder.
  The speed appears in two places: for moving left and for moving
  right.  Investigate whether it’s worth setting a variable to hold
  the speed.  A variable makes it easier to experiment with the
  player’s speed, but it is a bit more work to write the code in the
  first place.</p>
</li>
<li>
<p>Add another costume to the apple — look in the <em>Costumes</em> tab to see
  what you already have available from the “Cartoon fruit” bundle, or
  find your own images.  (Your code will be clearer if you then change
  the name of the sprite to <code>Fruit</code>!)  Each time the <code>Fruit</code> appears,
  choose randomly which costume to wear.  (Hint: a good place for this
  code is in the first part of the apple’s script, before the <code>while</code>
  loop.)  The Scratch/Python help will tell you the Pytch version of
  Scratch’s <code>switch costume</code> block, and how to choose things randomly.</p>
</li>
<li>
<p>Make the score-keeper jump up and down in celebration when the
  player catches an apple.  In Scratch you might use the <code>repeat</code>
  block.  Use the Scratch/Python help to find how to do this in Pytch.</p>
</li>
<li>
<p>Make there be a fixed number of apples — maybe 8.  Advanced: At the
  end of the game, make the score-keeper say something like “You got 5
  out of 8”.  You can use Python’s “f-strings” (<a href="https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings">read about them in
  the Python
  documentation</a>)
  to get the score-keeper to say this.</p>
</li>
</ul></div></div>